package com.core.cloudcommon.trace;

import org.slf4j.MDC;

/**
 * @author =====Lqj=====
 * @className TraceMDCManager
 * @description 链路追踪MDC管理器，用于在所有日志中自动添加链路ID
 * @create 2024/12/17 10:30
 **/
public class TraceMDCManager {

    /**
     * MDC中链路ID的键名
     */
    public static final String TRACE_ID_KEY = "traceId";

    /**
     * MDC中用户ID的键名
     */
    public static final String USER_ID_KEY = "userId";

    /**
     * MDC中用户名的键名
     */
    public static final String USER_NAME_KEY = "userName";

    /**
     * MDC中请求URI的键名
     */
    public static final String REQUEST_URI_KEY = "requestUri";

    /**
     * MDC中客户端IP的键名
     */
    public static final String CLIENT_IP_KEY = "clientIp";

    /**
     * 设置链路ID到MDC
     * @param traceId 链路ID
     */
    public static void setTraceId(String traceId) {
        if (traceId != null && !traceId.trim().isEmpty()) {
            MDC.put(TRACE_ID_KEY, traceId);
        }
    }

    /**
     * 获取MDC中的链路ID
     * @return 链路ID
     */
    public static String getTraceId() {
        return MDC.get(TRACE_ID_KEY);
    }

    /**
     * 设置用户ID到MDC
     * @param userId 用户ID
     */
    public static void setUserId(Long userId) {
        if (userId != null) {
            MDC.put(USER_ID_KEY, userId.toString());
        }
    }

    /**
     * 获取MDC中的用户ID
     * @return 用户ID
     */
    public static String getUserId() {
        return MDC.get(USER_ID_KEY);
    }

    /**
     * 设置用户名到MDC
     * @param userName 用户名
     */
    public static void setUserName(String userName) {
        if (userName != null && !userName.trim().isEmpty()) {
            MDC.put(USER_NAME_KEY, userName);
        }
    }

    /**
     * 获取MDC中的用户名
     * @return 用户名
     */
    public static String getUserName() {
        return MDC.get(USER_NAME_KEY);
    }

    /**
     * 设置请求URI到MDC
     * @param requestUri 请求URI
     */
    public static void setRequestUri(String requestUri) {
        if (requestUri != null && !requestUri.trim().isEmpty()) {
            MDC.put(REQUEST_URI_KEY, requestUri);
        }
    }

    /**
     * 获取MDC中的请求URI
     * @return 请求URI
     */
    public static String getRequestUri() {
        return MDC.get(REQUEST_URI_KEY);
    }

    /**
     * 设置客户端IP到MDC
     * @param clientIp 客户端IP
     */
    public static void setClientIp(String clientIp) {
        if (clientIp != null && !clientIp.trim().isEmpty()) {
            MDC.put(CLIENT_IP_KEY, clientIp);
        }
    }

    /**
     * 获取MDC中的客户端IP
     * @return 客户端IP
     */
    public static String getClientIp() {
        return MDC.get(CLIENT_IP_KEY);
    }

    /**
     * 设置完整的链路追踪信息到MDC
     * @param traceId 链路ID
     * @param userId 用户ID
     * @param userName 用户名
     * @param requestUri 请求URI
     * @param clientIp 客户端IP
     */
    public static void setTraceInfo(String traceId, Long userId, String userName, 
                                   String requestUri, String clientIp) {
        setTraceId(traceId);
        setUserId(userId);
        setUserName(userName);
        setRequestUri(requestUri);
        setClientIp(clientIp);
    }

    /**
     * 清理MDC中的链路追踪信息
     */
    public static void clear() {
        MDC.remove(TRACE_ID_KEY);
        MDC.remove(USER_ID_KEY);
        MDC.remove(USER_NAME_KEY);
        MDC.remove(REQUEST_URI_KEY);
        MDC.remove(CLIENT_IP_KEY);
    }

    /**
     * 清理MDC中的所有信息
     */
    public static void clearAll() {
        MDC.clear();
    }

    /**
     * 获取当前MDC中的所有信息
     * @return MDC信息的字符串表示
     */
    public static String getCurrentMDCInfo() {
        StringBuilder sb = new StringBuilder();
        sb.append("MDC{");
        sb.append("traceId=").append(getTraceId()).append(", ");
        sb.append("userId=").append(getUserId()).append(", ");
        sb.append("userName=").append(getUserName()).append(", ");
        sb.append("requestUri=").append(getRequestUri()).append(", ");
        sb.append("clientIp=").append(getClientIp());
        sb.append("}");
        return sb.toString();
    }

    /**
     * 检查MDC中是否存在链路ID
     * @return true-存在，false-不存在
     */
    public static boolean hasTraceId() {
        String traceId = getTraceId();
        return traceId != null && !traceId.trim().isEmpty();
    }

    /**
     * 从TraceContext同步信息到MDC
     */
    public static void syncFromTraceContext() {
        String traceId = TraceContext.getTraceId();
        Long userId = TraceContext.getUserId();
        String userName = TraceContext.getUserName();
        String requestUri = TraceContext.getRequestUri();
        String clientIp = TraceContext.getClientIp();
        
        setTraceInfo(traceId, userId, userName, requestUri, clientIp);
    }

    /**
     * 从MDC同步信息到TraceContext
     */
    public static void syncToTraceContext() {
        String traceId = getTraceId();
        String userIdStr = getUserId();
        String userName = getUserName();
        String requestUri = getRequestUri();
        String clientIp = getClientIp();
        
        if (traceId != null) {
            TraceContext.setTraceId(traceId);
        }
        if (userIdStr != null) {
            try {
                TraceContext.setUserId(Long.parseLong(userIdStr));
            } catch (NumberFormatException e) {
                // 忽略格式错误
            }
        }
        if (userName != null) {
            TraceContext.setUserName(userName);
        }
        if (requestUri != null) {
            TraceContext.setRequestUri(requestUri);
        }
        if (clientIp != null) {
            TraceContext.setClientIp(clientIp);
        }
    }
}
